<?php

/** une abstraction des fichiers charge sur le serveur.
 * @author Sebastian Mosser
 * @date 2006
 * @version 1.0
 */
 
 
class UploadedFile {

    private $_originalFileName;
    private $_mimeType;
    private $_fileSize;
    private $_serverTempName;
    private $_errNum;

		const REGULAR = "reg";
		const BZ2 = "bz2";
		const GZIP = "gz";
		const GUESS = "guess";

  /** constructeur standar de fichier uploade.
     * @param $formName le nom sous lequel le fichier a ete charge
     * @throw une exception si le parametre n'est pas valide
     */
    public function __construct($formName) {

      // Recuperation du fichier
	    $fileItem = PropRetriever::getArray($_FILES,$formName);     

      if (count($fileItem) == 0) {
         $msg =  "L'élément de formulaire de correspond pas à un fichier !";
         throw new Exception($msg,0);
      }

      // Récupération des infos sur le fichier générées par PHP
    	$this->_originalFileName = $fileItem["name"];
    	$this->_mimeType = $fileItem["type"];
    	$this->_fileSize = $fileItem["size"];
    	$this->_serverTempName = $fileItem["tmp_name"];
    	$this->_errNum = $fileItem["error"];
   }

	/** Renvoie le nom du fichier sur la machine de l'utilisateur. 
	 */
	public function getOriginalName() {return $this->_originalFileName; }
	
	public function getTempName() { return $this->_serverTempName; }

    /** Verification globale sur un fichier charge
     * @return True si le fichier passe, une description du probleme sinon.
     */
  public function checkFile() {
        
    // L'utilisateur a t'il selectionné quelque chose ?
    if ($this->_fileSize == 0)
        return "Vous n'avez pas choisi de fichier à charger !";
    
    // Est-ce bien un fichier téléchargé :
    if (! is_uploaded_file($this->_serverTempName))
        return "Attaque par téléchargement de fichier critique détectée !";
    
    // Verification du code erreur :
    switch ($this->_errNum) {
      case UPLOAD_ERR_INI_SIZE:
         return "La taille du fichier chargé est trop grande pour le serveur !";
      case UPLOAD_ERR_FORM_SIZE:
         return "La taille du fichier chargé est trop grande pour cette page !";
      case UPLOAD_ERR_PARTIAL:
          return "Le fichier n'a pas été chargé dans sa totalité !";
      case UPLOAD_ERR_NO_FILE:
          return "Le fichier n'a pas été chargé sur le serveur !";
    }
  
    return True;
  }


    /** Deplace un fichier charge vers sa destination finale
     * @param $filePath destination
     * @return True si c'est bon, une description de l'erreur sinon.
     */
    public function moveToDest($filePath) {
        $check = $this->checkFile();
        if ($check === True)
            move_uploaded_file($this->_serverTempName,$filePath);
        else
            return $check;
        return True;
    }
    
    
    /** Lit un fichier telecharge
     * @param $compressType un type de compression, par défaut 'guess'
     * @warning en mode 'guess', la fonction teste sur l'extension de fichier.
     * @return un tableau a 2 elements.
     * @warning Le retour fonctionne de la maniere suivante : 
     *  - le premier element est un booleen indiquant si tout c'est bien passe
     *    - Si True, le second element est le contenu du fichier.
     *    - Si False, le second element est la description du probleme.
     
     */
    public function readAFile($compressType = self::GUESS) {
    	
    	$check = $this->checkFile();
    	$read = array();

    	if ($check !== True ){
    		$read[0] = False;
    		$read[1] = $check;
    		return $read;
    	}
    	
    	$read[0] = True;

    	if ($compressType == self::GUESS) {
    		// Recuperation de l'extension :
    		$parts = explode('.',$this->_originalFileName);
    		$ext = $parts[count($parts) - 1];
    		switch ($ext) {
    			case "bz2":
    				$compressType = self::BZ2;
    				break;
    			case "gz":
    				$compressType = self::GZIP;
    				break;
    			default: // Par defaut, fichier regulier
    				$compressType = self::REGULAR;
    		}
    	}
    	
    	switch($compressType) {
    		case self::BZ2: 
    			$read[1] = $this->readABz2File();
    			break;
    		case self::GZIP:
    			$read[1] = $this->readAGzFile();
    			break;
    		case self::REGULAR:
    			$read[1] = $this->readARegularfile();
    	}
    	
    	return $read;
    }
    
    
    
    /** Lit le contenu d'un fichier telecharge
     * @return la chaine de caracteres ad'hoc. 
     */
    private function readARegularFile() {
        return file_get_contents($this->_serverTempName);
    }
    
    /** Lit le contenu d'un fichier telecharge au format Bz2
     * @return la chaine de caracteres ad'hoc. 
     */
    private function readABz2File() {
      $readData = "";
      $bz = bzopen($this->_serverTempName,"r");
      while (! feof($bz))
        $readData .= bzread($bz);
      bzclose($bz);
      return $readData;
    }
    
    /** Lit le contenu d'un fichier telecharge au format Gz
     * @return la chaine de caracteres ad'hoc. 
     */
    private function readAGzFile() {
        $result = array();
        if ($check === True) {
            $readData = "";
            $gz = gzopen($this->_serverTempName,"r");
            while (! feof($gz))
                $readData .= gzread($gz);
            gzclose($bz);
            
            $result[0] = True;
            $result[1] = $readData;
        }
        else {
          $result[0] = False;
          $result[1] = $check;
        
        }
        return $result;
    }
    
    
    

}

?>